#include "utility.h"
#include "3DModel/Ball.h"
#include "3DModel/Cube.h"
#include "3DModel/Panel.h"
#include "3DModel/Pyramid.h"


Model3D::Model3D() 
	: vao(0), vboIndex(0), vboVertex(0), vertexCount(0), indexCount(0)
{

}

Model3D::Model3D(GLuint vao, GLuint vboVertex, GLuint vboIndex, int vertexCount, int indexCount)
{
	this->vao = vao;
	this->vboIndex = vboIndex;
	this->vboVertex = vboVertex;
	this->vertexCount = vertexCount;
	this->indexCount = indexCount;
}

void Model3D::deleteBuffer()
{
	if (vao)
	{
		glDeleteVertexArrays(1, &vao);
	}
	if (vboIndex)
	{
		glDeleteBuffers(2, &vboIndex);
	}
	if (vboVertex)
	{
		glDeleteBuffers(1, &vboVertex);
	}
}

void Model3D::Draw()
{
	glBindVertexArray(vao);
	if (vboIndex)
	{
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndex);
		glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, OFFSET_POINTER(0));
	}
	else
	{
		glDrawArrays(GL_TRIANGLES, 0, vertexCount);
	}
}



Model3D Loader3DModel(const float verties[], const int pervertexFloatCount, const int vertexCount,
	                const unsigned int indiexs[], const int indexCount,
	                GLuint posAttrib, GLuint normalAttrib, GLuint texAttirb)
{
	GLuint vao = 0;
	GLuint vbo[2]{ 0 };
	GLsizei vertexSize = pervertexFloatCount * sizeof(float);

	
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	glGenBuffers(2, vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
	glBufferData(GL_ARRAY_BUFFER, vertexSize* vertexCount, verties, GL_STATIC_DRAW);
	if (posAttrib != -1)
	{
		glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, vertexSize, OFFSET_POINTER(0));
		glEnableVertexAttribArray(posAttrib);
	}

	if (normalAttrib != -1)
	{
		glVertexAttribPointer(normalAttrib, 3, GL_FLOAT, GL_FALSE, vertexSize, OFFSET_POINTER(sizeof(float)*3));
		glEnableVertexAttribArray(normalAttrib);
	}

	if (texAttirb != -1)
	{
		glVertexAttribPointer(texAttirb, 2, GL_FLOAT, GL_FALSE, vertexSize, OFFSET_POINTER(sizeof(float)*6));
		glEnableVertexAttribArray(texAttirb);
	}

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[1]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indexCount, indiexs, GL_STATIC_DRAW);

	glBindVertexArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	return Model3D{ vao, vbo[0], vbo[1], vertexCount, indexCount };
}

Model3D LoadPanel(GLuint posAttrib, GLuint normalAttrib, GLuint texAttirb)
{

	return Loader3DModel(PanelVertices, PanelPerVertexFloatCount, PanelVertexCount, PanelIndices, PanelIndexCount, posAttrib, normalAttrib, texAttirb);
}

Model3D LoadBall(GLuint posAttrib, GLuint normalAttrib)
{
	return Loader3DModel(BallVertices, BallPerVertexFloatCount, BallVertexCount, BallIndices, BallIndexCount, posAttrib, normalAttrib, -1);
}

Model3D LoadCube(GLuint posAttrib, GLuint normalAttrib)
{
	return Loader3DModel(CubeVertices, CubePerVertexFloatCount, CubeVertexCount, CubeIndices, CubeIndexCount, posAttrib, normalAttrib, -1);
}

Model3D LoadPyramid(GLuint posAttrib, GLuint normalAttrib)
{
	return Loader3DModel(PyramidVertices, PyramidPerVertexFloatCount, PyramidVertexCount, PyramidIndices, PyramidIndexCount, posAttrib, normalAttrib, -1);
}






